
	/***********************************************************************************************

		@NAPI
		Module: Jsl (native api)

		Base:
			mod	__ni_init							(data*)

		Console api:
    	mod	__ni_cns_debug				(msg)
    	mod	__ni_cns_info					(msg)
    	mod	__ni_cns_warn					(msg)
    	mod	__ni_cns_error				(msg)
    	mod	__ni_cns_log					(msg)

		Script api:
			v		__ni_jvs_exec					(script)

		Timer api:
			tid	__ni_tmr_create				(action, interval*, n*)
			b		__ni_tmr_remove				(tid)

		Info api:
			jv	__ni_inf_jsv					()
			tp	__ni_inf_sys					()
			tp	__ni_inf_dev					()
			os	__ni_inf_os						()
			ua	__ni_inf_ua						()

			url	__ni_inf_url_app			()
			url	__ni_inf_url_lqd			()

		Connector api:
			spt	__ni_cnt_support			()
    	mod __ni_cnt_create				(cn)
    	mod	__ni_cnt_open					(cn)
    	mod __ni_cnt_close				(cn)
    	dt 	__ni_cnt_send					(cn, data)

		Note:
			ua -> { ua, uav, uavId }

	************************************************************************************************/

	//-------------------------------------------------------------------------------
	//0-shared
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_create = function(cn) {
		if(cn.__prt !== "ws")	this.__ni_cnt_hcreate && this.__ni_cnt_hcreate(cn)
		else this.__ni_cnt_wcreate && this.__ni_cnt_wcreate(cn)
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_open = function(cn) {
		if(cn.__prt !== "ws")	this.__ni_cnt_hopen(cn)
		else this.__ni_cnt_wopen(cn)
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_close = function(cn) {
		if(cn.__prt !== "ws")	this.__ni_cnt_hclose(cn)
		else this.__ni_cnt_wclose(cn)
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_send = function(cn, data) {
		if(cn.__prt !== "ws")	return this.__ni_cnt_hsend(cn, data)
		else return this.__ni_cnt_wsend(cn, data)
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_jvs_exec = function(script) {
		return eval(script)
	}
	//@sys All - for http put/delete all the browsers returns differents codes
	//200: 	ok
	//201: 	created 	 											(put)
	//409:  confict - file already present 	(put)
	//204: 	no content 											(put/delete)
	//1223:	ie map 204 -> 1223							(put)
	//0:		empty, no headers 							(put, delete, http: cross domain violation, file: file not found)
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_herr = function(cn, status) {
		var sid, mth, b

		sid = jsl.info("system.id")
		mth = cn.method && cn.method() || "put"

		b = true
		if(status === 200)																							b = false
		else if(status === 201 	&& mth === "put")												b = false
		else if(status === 409 	&& mth === "put")												b = false
		else if(status === 204 	&& (mth === "put" || mth === "delete"))	b = false
		else if(status === 1223 && sid === "Explorer" && mth === "put")	b = false
		else if(status === 0		&& mth === "put")												b = false
		else if(status === 0		&& mth === "delete")										b = false
		else if(status === 404	&& mth === "delete")										b = false

		return b
	}

	//-------------------------------------------------------------------------------
	//1-liquidbox
	//-------------------------------------------------------------------------------
	if(this["@liquidbox"]) {

	//-------------------------------------------------------------------------------
	//init
	//-------------------------------------------------------------------------------
	jsl.__ni_init = function() {
		try {
			//data
			//-------------------------------------------------------------------------------
			this.__ni_tmr_dt			= []
			this.__ni_tmr_dt.tid	= 0

			this.__ni_cnt_cns			= {}
			this.__ni_cnt_fid			= 0

			this.__ni_cwd = __ni_fle_dcwd().replace(/\\/g, "/")
			this.__ni_jsv = __ni_jsl_jsv()
			this.__ni_os 	= __ni_jsl_os()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	//Log api
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_debug = function(msg) {
		try {
			__ni_jsl_print(msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_info = function(msg) {
		try {
			__ni_jsl_print(msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_warn = function(msg) {
		try {
			__ni_jsl_print(msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_error = function(msg) {
		try {
			__ni_jsl_print(msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_log = function(msg) {
		try {
			__ni_jsl_print(msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	//Timer api
	//-------------------------------------------------------------------------------
	jsl.__ni_tmr_create = function(action, interval, n) {
		try {
			var i, tid, c, dt

			c		= 1
			i		= interval === 0 ? 1 : (n || Infinity)
			dt 	= this.__ni_tmr_dt
      tid = "T" + dt.tid++
			dt[tid]	= {

				tid:	tid,
				i: 		interval,
				ts:		0,

				f: function() {
					try {
						i--
						action(tid, c++)

						//the action can have removed the timer
						if(dt[tid] && !i)
							jsl.__ni_tmr_remove(tid)
					}
					catch(e) {
						jsl.__ni_tmr_remove(tid)
						jsl.captureError(e, "Timer(tid)", [ tid ])
					}
				}
			}

			dt.push(dt[tid])
			return tid
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_tmr_remove = function(tid) {
		try {
      var b, dt

      dt = this.__ni_tmr_dt

      if(dt[tid] != null) {

				delete dt[tid]
				b = true

				for(var a = 0, l = dt.length; a < l; a++)
					if(tid === dt[a].tid) {
						dt.splice(a, 1)
						break
					}
			}

      return !!b
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	//Info api
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_ua = function() {
		return {
			id: 	"LiquidBox",
			v:		jsl.__v,
			vid:	jsl.__v + ""
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_os = function() {
		return this.__ni_os
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_jsv = function() {
		return this.__ni_jsv
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_sys = function() {
		return "native"
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_dev = function() {
		return "desktop"
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_url_app = function() {
		try {
			var cwd

			cwd = this.__ni_cwd
			if(cwd.charAt(0) === "/") cwd = cwd.slice(1)

			return "file:///" + cwd
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_url_lqd = function() {
		try {
			var cwd

			cwd = this.__ni_cwd
			if(cwd.charAt(0) === "/") cwd = cwd.slice(1)
			return "file:///" + cwd + "/liquid"
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	//connector
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_support = function() {
		return {
			ws: 	true,
			http: true,
			file: true
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hopen = function(cn) {
		try {
			var obj, url, id

			url = cn.url(true)

			//file
			if(url.scheme() === "file")
				url = url.parent() + "/" + url.resource()

			//jsonp
			else if(cn.jsonp && cn.jsonp()) {//!
				if(url.query().search(/=@callback@($|#|&)/i) === -1)	throw jsl.MisuseError("BadJsonpUrl", [ url ])//!

				id	= "__ni_cnt_f" + this.__ni_cnt_fid++
				url = (url + "").replace(/=@callback@($|#|&)/i, "=jsl." + id + "$1")
				this[id] = function(data) { cn.__receive(data) }
			}

			//other
			else
				url = url + ""

			cn.__ni_url = url

			__ni_jsl_hopen(cn)
			__ni_jsl_hopt(cn, 0, url)
			__ni_jsl_hopt(cn, 2, cn.async())

			if(cn.method) __ni_jsl_hopt(cn, 1, cn.method())

			if(cn.headers) {
				obj = cn.headers()
				for(id in obj)
					__ni_jsl_hopt(cn, 3, id + ":" + obj[id])
			}

			cn.__exec()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hclose = function(cn) {
		try {
			var fn, cns

			fn 	= jsl.__ni_cnt_htimer
			cns	= fn.cns

			for(var id in cns)
				if(cns[id].cn === cn)
					delete cns[id]

			__ni_jsl_hclose(cn)
			cn.__exec()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hsend = function(cn, data) {
		try {
			var dt, s, id, hds, ctt, mth

			__ni_jsl_hopt(cn, 4, cn.timeout())

			if(data) {//!
				mth = cn.method && cn.method()
				if(mth === "get" || mth === "delete")	throw jsl.ParamError("NotRequired:data")//!

				hds = cn.headers()
				for(id in hds)
					if(id.toLowerCase() === "content-type") {
						ctt = true
						break
					}

				if(ctt)
					s = data + ""
				else {

					if(typeof data !== "string") {
						s = []
						for(id in data) s.push(encodeURIComponent(id).replace(/%20/g,"+") + "=" + encodeURIComponent(data[id]).replace(/%20/g,"+"))
						s = s.join("&")
					}
					else
						s = data.replace(/%20/g,"+")
				}
			}

			dt 			= __ni_jsl_hsend(cn, s || "")
			dt.cn 	= cn
			dt.url	= cn.__ni_url

			if(cn.async())
				this.__ni_cnt_htimer(dt)

			else if(jsl.__ni_cnt_herr(cn, dt.code))
				cn.__error(jsl.NativeError("ComunicationError", [ dt.url, "(code: " + dt.code + ")" ]), dt.code)

			return cn.async() ? cn : cn.__receive(dt.data || "")
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_htimer = function(dt) {
		try {
			var fn

			fn = arguments.callee
			if(!fn.tid) {
				fn.cns 	= {}
				fn.tid 	= jsl.timer(function() {
					try {
						var dt

						while((dt = __ni_jsl_hread())) {

							dt.cn 	= fn.cns[dt.id].cn
							dt.url 	= fn.cns[dt.id].url
							delete fn.cns[dt.id]

							if(dt.code === 28)
								dt.cn.__timeout(dt.url)
							if(jsl.__ni_cnt_herr(dt.cn, dt.code))
								dt.cn.__error(jsl.NativeError("ComunicationError", [ dt.url, "(code: " + dt.code + ")" ]), dt.code)
							else
								dt.cn.__receive(dt.data)
						}

						if(dt === 0) {
							jsl.removeTimer(fn.tid)
							fn.tid = null
						}
					}
					catch(e) {
						//htimer must continue
						jsl.captureError(e, "jsl.__ni_cnt_htimer()")
					}
				}, 70)
			}

			fn.cns[dt.id] = dt
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}

	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wopen = function(cn) {
		try {
			var url, host, path, port, ssl

			url		= cn.url()
			ssl		= url.scheme() === "wss"
			host 	= url.host()
			port 	= url.port()
			path	= url.path()

			__ni_jsl_wopen(cn, host, port, path, ssl)
			this.__ni_cnt_wtimer(cn)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wclose = function(cn) {
		try {
			__ni_jsl_wclose(cn)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wsend = function(cn, data) {
		try {
			__ni_jsl_wsend(cn, data + "")
			return cn
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wtimer = function(cn) {
		try {
			var f

			f = arguments.callee
			this.__ni_cnt_cns[cn.__ncn] = cn

			if(!f.tid)
				f.tid = jsl.timer(function() {
					var dt, cn, e, id, cns

					cns	= jsl.__ni_cnt_cns
					while((dt = __ni_jsl_wread())) {

						cn 	= cns[dt.ncn]
						e		= dt.evt

						if(!e)
							cn.__exec()
						else if(e === 1)
							cn.__receive(dt.dt)
						else {
							delete cns[dt.ncn]
							if(e === -1)	cn.__error(jsl.NativeError("SocketError", [ cn.url() + "" ]))
							else 					cn.__exec()
						}
					}

					for(id in cns) break;
					if(id == null) {
						jsl.removeTimer(f.tid);
						f.tid = null
					}

				}, 70)
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	}

	//-------------------------------------------------------------------------------
	//2-web
	//-------------------------------------------------------------------------------
	else {

	//-------------------------------------------------------------------------------
	//init
	//-------------------------------------------------------------------------------
	jsl.__ni_init = function() {
		try {

			//data
			//-------------------------------------------------------------------------------
			this.__ni_tmr_dt			= {}
			this.__ni_tmr_dt.tid	= 0
			this.__ni_cnt_fid 		= 0

			//-------------------------------------------------------------------------------
			if(window.addEventListener) {
				window.addEventListener("load"	, function() { jsl.__run() 	}, false)
				window.addEventListener("unload", function() { jsl.__exit()	}, false)
			}
			//@sys: Explorer 8.0.6 - typeof attachEvent === "object"
			else if(window.attachEvent) {
				window.attachEvent("onload"		, function() { jsl.__run()	})
				window.attachEvent("onunload"	, function() { jsl.__exit()	})
			}//!
			else
				throw jsl.NativeError("NotSupported:Listeners")//!
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}

	//-------------------------------------------------------------------------------
	//Log api
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_debug = function(msg) {
		try {
			var print

			if(window.console)
				if(console.debug != null)			print = function(msg) { console.debug(msg) 	}
				else if(console.log != null)	print = function(msg) { console.log(msg)		}

			print && print("liquid>> "	+ msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_info = function(msg) {
		try {
			var print

			if(window.console)
				if(console.info != null)			print = function(msg) { console.info(msg) }
				else if(console.log != null)	print = function(msg) { console.log(msg) 	}

			print && print("liquid>> " + msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_warn = function(msg) {
		try {
			var print

			if(window.console)
				if(console.warn != null)			print = function(msg) { console.warn(msg) }
				else if(console.log != null)	print = function(msg) { console.log(msg)	}

			print && print("liquid>> " + msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_error = function(msg) {
		try {
			var print

			if(window.console)
				if(console.error != null)			print = function(msg) { console.error(msg) 	}
				else if(console.log != null)	print = function(msg) { console.log(msg)		}

			print && print("liquid>> "	+ msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cns_log = function(msg) {
		try {
			if(window.console && console.log != null)	console.log(msg)
			return this
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	//Timer api
	//-------------------------------------------------------------------------------
	jsl.__ni_tmr_create = function(action, interval, n) {
		try {
			var i, tid, nid, c

			c		= 1
			i		= interval === 0 ? 1 : (n || Infinity)
      tid = "T" + this.__ni_tmr_dt.tid++
			nid	= setTimeout(function() {
				try {
					i--
					action(tid, c++)

					//the action can have removed the timer
					if(jsl.__ni_tmr_dt[tid] != null)
						if(i)	jsl.__ni_tmr_dt[tid] = setTimeout(arguments.callee, interval)
						else	jsl.__ni_tmr_remove(tid)

				}
				catch(e) {
					jsl.captureError(e, "Timer(tid)", [ tid ])
				}
			}, interval)

			this.__ni_tmr_dt[tid] = nid
			return tid
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_tmr_remove = function(tid) {
		try {
      var b

      if(this.__ni_tmr_dt[tid] != null) {
				clearTimeout(this.__ni_tmr_dt[tid])
				delete this.__ni_tmr_dt[tid]
				b = true
			}

      return !!b
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}

	//-------------------------------------------------------------------------------
	//Info api
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_jsv = function() {
		try {
			var tmp, p, a, jsv, node

			if(arguments.callee.jsv)
				return arguments.callee.jsv

			else {

	      p	= document.getElementsByTagName("head")//!
	      if(!p)	throw jsl.NativeError("NotFound:<header>")//!

	      p = p[0]
				tmp = jsl.__tmp

				tmp.lang	= false
				tmp.type	= false
				tmp.jsv		= 0

	      node    	= document.createElement("script")
	      node.text	= "jsl.__tmp.type=true"
				node.setAttribute("type", "text/javascript")
	      p.appendChild(node)
	      p.removeChild(node)

				//@sys: Opera 11.5 does not support the language attribute
	      node    	= document.createElement("script")
	      node.text	= "jsl.__tmp.lang=true"
	      node.setAttribute("language", "javascript")

	      p.appendChild(node)
	      p.removeChild(node)

	      if(tmp.lang || tmp.type)
					//decimal add - arithmetic error: 1.000000000008
		      for(a = 1.3; a <= 2; a = +(a + 0.1).toFixed(1)) {

						jsv = a

						//these two ways can generate different results (is taken the newer)
						//current standard attribute
						if(jsl.__tmp.type)  {
			        node    	= document.createElement("script")
			        node.text	= "jsl.__tmp.jsv=" + jsv

							node.setAttribute("type", "text/javascript" + jsv)
							node.type = "text/javascript" + jsv
						}

						//deprecated attribute
						else {
							node      = document.createElement("script")
							node.text	= "jsl.__tmp.jsv=" + jsv

							//@sys: Chrome 15, Safari 5 doesn't work if we set: node.language = ..
			        node.setAttribute("language", "javascript" + jsv)
			        node.language = "javascript" + jsv
						}

			      p.appendChild(node)
		        p.removeChild(node)
		        if(tmp.jsv !== jsv) break
		      }

				return arguments.callee.jsv = tmp.jsv
			}
    }
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_sys = function() {
		return "web"
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_dev = function() {
		var os, mb

		os = this.__ni_inf_os()
		mb = os === "Windows CE" || os === "Windows Phone" || os === "iOS" || os === "Android"
		return  mb ? "mobile" : "desktop"
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_os = function() {
		try {
			var os, s

			if(arguments.callee.os)
				return arguments.callee.os

			else {

				s = navigator.platform

				if(s.search(/windows\s+ce/i) !== -1)					os = "Windows CE"
				else if(s.search(/windows\s+phone/i) !== -1)	os = "Windows Phone"
				else if(s.search(/win/i) !== -1)							os = "Windows"
				else if(s.search(/iphone|ipod|ipad/i) !== -1)	os = "iOS"
				else if(s.search(/mac/i) !== -1)							os = "MacOS"
				else if(s.search(/android/i) !== -1)					os = "Android"
				else if(s.search(/linux/i) !== -1)						os = "Linux"
				else if(s.search(/x11/i) !== -1)							os = "Unix"
				else																					os = "unknown"

				arguments.callee.os = os
				return arguments.callee.os
			}
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_ua = function() {
		try {
			var uas, ua, a, l, dt, p, ix

			if(arguments.callee.ua)
				return arguments.callee.ua

			else {

				//s: string, ss: substring, vs: version search
				uas = [
								{ id: "Firefox", 	s: navigator.userAgent	, ss: "firefox" 										},
								{ id: "Safari", 	s: navigator.vendor			, ss: "apple"		, vs: "version" 		},
								{ id: "Chrome", 	s: navigator.userAgent	, ss: "chrome"											},
								{ id: "Android", 	s: navigator.vendor			, ss: "google"	, vs: "version" 		},
								{ id: "Explorer", s: navigator.userAgent	, ss: "msie"		, vs: "msie" 				},
								{ id: "Explorer", s: navigator.userAgent	, ss: "trident"	, vs: "rv" 					}, //IE >= 11
								{ id: "Opera"		, s: navigator.userAgent 	, ss: "opera" 	, vs: "version" 	 	}
							]

				ua = {
					id: 	"unknown",
					vid: 	"unknown",
					v:		-1
				}

				l = uas.length
				for(a = 0; a < l; a++) {

					dt = uas[a]

					//@sys: data.s can be undefined (ex: opera 10.51)
					if(dt.s && dt.s.search(RegExp(dt.ss, "i")) !== -1) {

						ua.id	= dt.id
						p 		= dt.vs || dt.id
						ix 		= navigator.userAgent.search(RegExp(p, "i"))

						if(ix != -1) {
							ua.vid = navigator.userAgent.slice(ix + p.length + 1).match(/[\d\.]+/)
							ua.vid = ua.vid ? ua.vid[0] : "unknown"
						}
						else {
							ix = navigator.appVersion.search(RegExp(p, "i"))

							if(ix != -1) {
								ua.vid = navigator.appVersion.slice(ix + p.length + 1).match(/[\d\.]+/)
								ua.vid = ua.vid ? ua.vid[0] : "unknown"
							}
						}

	          if(ua.vid !== "unknown") {
	            if((ix = ua.vid.indexOf(".")) !== -1)
			          ua.v = parseFloat(ua.vid.slice(0, ix + 1) + ua.vid.slice(ix + 1).replace(/\./g, ""))
	            else
	              ua.v = parseInt(ua.vid)

							if(isNaN(ua.v))
								ua.v = -1
						}
						break
					}
				}

				return arguments.callee.ua = ua
			}
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_url_app = function() {
		try {

			if(arguments.callee.url)
				return arguments.callee.url

			else
				arguments.callee.url = (document.location + "").match(/^(.+?)(#.*)?$/)[1]

			return arguments.callee.url
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_inf_url_lqd = function() {
		try {
			var ns, l, lc, re, a, src, url

			if(arguments.callee.url)
				return arguments.callee.url

			else {
				ns 	= document.getElementsByTagName("script")
				lc 	= document.location + ""
				re	= /liquid\d+\.js(\?.*)?$/

				l = ns.length
				for(a = 0; a < l; a++) {

					src = ns[a].src.replace(/\s+/g, "")

					if(re.test(src)) {

						if(url) {
							url = null
							break
						}
						//@sys - Explorer v.8.0.6001.18702/Firefox v.3.5.6 &C
						//IE maintains the value passed at <script>.src but other browser normalize it to absolute url
						if(!src.match(/^\s*[^:\s]+\s*:\s*\/\s*\//i))
							src = (lc + "").split("/").slice(0, -1).join("/") + "/" + src.match(/^(?:[\s\\\/]*)([\s\S]+)$/)[1]

						url = src.replace(/\\/g, "/")
					}
				}

				//ambiguity
				if(url === null)	throw jsl.MisuseError("LiquidUrlNotFound2")
				else if(!url)			jsl.__ni_cns_warn(jsl.message("LiquidUrlNotFound"))

				return arguments.callee.url = url
			}
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	//connector
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_support = function() {
		var spt

		spt = {
			//@sys: Safari 5.0 - typeof WebSocket === "object" (not "function")
			ws:		jsl.__go.WebSocket	!= null,
			http: true,
			file: false
		}

		return spt
	}
	//-------------------------------------------------------------------------------
	//private connector: WS API
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wcreate = function(cn) {//!
		if(!window.WebSocket)	throw jsl.NativeError("NotSupported:websocket")//!
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wopen = function(cn) {
		var prt, ncn, url

		url = cn.url(true) + ""
		prt = cn.protocol()

		if(prt)	ncn = new WebSocket(url, prt)
		else		ncn = new WebSocket(url)

		cn.__ni_cn = ncn
		//!
		//3-> The connection is closed or couldn't be opened.
		if(ncn.readyState === 3)	throw jsl.NativeError("OperationFailed")//!

		ncn.onopen 		= function() 	{ cn.__exec()	}
		ncn.onmessage = function(e)	{ cn.__receive(e.data) }
		ncn.onerror 	= function(e) { cn.__error(jsl.NativeError("UnknownSocketError", [ url ])) }

		ncn.onclose 	= function(e) {
			if(e.code == 1000)	cn.__exec()
			else 								cn.__error(jsl.NativeError("SocketError", [ url, e.code, e.reason ]))
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wclose = function(cn) {
		cn.__ni_cn.close()
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_wsend = function(cn, data) {
		cn.__ni_cn.send(data + "")
		return cn
	}
	//-------------------------------------------------------------------------------
	//private connector: HTTP API
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hcreate = function(cn) {
		cn.__ni_cns = []
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hopen = function(cn) {
		try {
			var url, ncn, hds, id, dt, src, cdm, jsp

			//anti cache on get requests
			url = cn.url(true)

			if(cn.method() === "get")	url = url + (url.query() ? "&" : "?") + "jsl=" + (+new Date + "" + Math.random())
			else url += ""

			cdm	= cn.url().host() !== jsl.info("app.url").host()
			jsp = cn.jsonp && cn.jsonp()

			//1-xhr
			//-------------------------------------------------------------------------------
			if(!cdm && !jsp) {

				//@sys: Opera v.9.64 	- impossible reuse an xhr if the last open has caused an error (always INVALID_STATE_ERR)
				//@sys: Explorer 8 		- xhr is unreliable, it is better use the ActiveX. Vice versa strange and obscure behaviors
				if(window.ActiveXObject)				ncn = new window.ActiveXObject("MSXML2.XMLHTTP.3.0")
				else if(window.XMLHttpRequest) 	ncn = new window.XMLHttpRequest()//!
				else 														throw jsl.NativeError("NotSupported:XmlHttpRequest/ActiveX(MSXML2.XMLHTTP.3.0)")//!

				//onreadystatechange always called also for sync operations
				//@sys: Explorer 8 - xhr.onreadystatechange = undefined throw an error -> e.message = 'NotImplemented'
				ncn.onreadystatechange = function() {
					var cn, data

					//sys: Firefox 6 and other.. - call xhr.abort fires the onreadystatechange because the
					//state is changed. The state value is 4 and is not changed to 0
					//The onreadystatechange with state 4 can be called also after the xhr.abort, therefore the onreadystatechange
					//can be called 2 time instead of 0 in the abort case.
					if(ncn.readyState === 4) {

						//1-alredy closed
						if(dt.state === 2)
							return

						//2-timeout to execute
						//the data can be processed before the execution of the timeout action
						//if the system was blocked by a js execution for some time.
						if(dt.tmo && new Date - dt.tme > dt.tmo) return

						//3-ok
						if(dt.tmo) jsl.__ni_tmr_remove(dt.tid)

						//@sys: Firefox - after the clean (xhr abort) the responseText become an empty string
						data = ncn.responseText
						jsl.__ni_cnt_hclean(dt)

						cn = dt.cn
						if(jsl.__ni_cnt_herr(cn, ncn.status))
							cn.__error(jsl.NativeError("ComunicationError", [ dt.url, "(code: " + ncn.status + ")" ]), ncn.status)

						dt.data = cn.__receive(data || "")
					}
				}

				//@sys: Explorer 8 	- toUpperCase because the delete method in lower case is not recognized
				//										(on TomCat: 501 not implemented)
				ncn.open(cn.__prt !== "file" ? cn.method().toUpperCase() : "GET", url, cn.async())

				hds = cn.headers()

				if(hds)
				for(id in hds) ncn.setRequestHeader(id, hds[id])
			}

			//2-script tag
			//-------------------------------------------------------------------------------
			else {
				ncn = document.createElement("script")
				ncn.type = "text/javascript"

				ncn.onerror = ncn.onreadystatechange = function () {

					if(!this.readyState || this.readyState === "loaded" || this.readyState === "complete")

						//1-error
						if(jsl[id]) {
							jsl.__ni_cnt_hclean(dt)
							cn.__error(jsl.NativeError("ComunicationError", [ ncn.src ]))
						}

						//2-content loaded and evaluated, timeout or already error
						else
							return
    		}

				if(jsp) {//!
					if(jsl.Url(url).query().search(/=@callback@($|#|&)/i) === -1)	throw jsl.MisuseError("BadJsonpUrl", [ url ])//!

					id	= "__ni_cnt_f" + this.__ni_cnt_fid++
					src = url.replace(/=@callback@($|#|&)/i, "=jsl." + id + "$1")

					this[id] = function(data) {

						//1-alredy closed
						if(dt.state === 2)
							return

						//2-timeout to execute
						//the data can be processed before the execution of the timeout action
						//if the system was blocked by a js execution for some time.
						if(dt.tmo && new Date - dt.tme > dt.tmo) return

						//3-ok
						if(dt.tmo) jsl.__ni_tmr_remove(dt.tid)
						jsl.__ni_cnt_hclean(dt)
						cn.__receive(data)
					}
				}
				else
					src = url
			}

			cn.__ni_cns.push(dt = {
				cn:			cn,
				ncn: 		ncn,
				url:		url,
				async:	cn.async(),
				src:		src,
				id:			id,
				fn:			cn.__oq[cn.__oq.length - 1],
				state:	0
			})

			if(!arguments[1])
				cn.__exec()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hclose = function(cn) {
		try {
			var cns

			cns = cn.__ni_cns
			while(cns.length) this.__ni_cnt_hclean(cns.shift())
			cn.__exec()
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hsend = function(cn, data) {
		try {
			var v, cns, dt, ncn, id, mth, s, hds, ctt

			cns = cn.__ni_cns
			dt 	= cns.length && cns[cns.length - 1]
			if(dt.state !== 0) {
				this.__ni_cnt_hopen(cn, true)
				dt = cns[cns.length - 1]
			}

			v		= this
			ncn = dt.ncn

			//0-timeout (set before all so the sync xhr.send can disable it)
			//-------------------------------------------------------------------------------
			dt.tmo = cn.timeout()
			if(dt.tmo)
				dt.tid = this.__ni_tmr_create(function() {
					jsl.__ni_cnt_hclean(dt)
					cn.__timeout(dt.url)
				}, dt.tmo, 1)

			dt.tme 		= new Date
			dt.state 	= 1

			//1-jsonp
			//-------------------------------------------------------------------------------
			if(dt.src) {
				ncn.src = dt.src
				document.body.appendChild(ncn);
			}

			//2-xhr
			//-------------------------------------------------------------------------------
			else {

				mth = cn.method()//!
				if(data && (mth === "get" || mth === "delete"))	throw jsl.ParamError("NotRequired:data")//!

				//2.1-data preparation
				//-------------------------------------------------------------------------------
				if(mth === "post") {

					hds = cn.headers()
					for(id in hds)
						if(id.toLowerCase() === "content-type") {
							ctt = true
							break
						}

					if(ctt || data === "")
						s = data + ""
					else {

						ncn.setRequestHeader("Content-type", "application/x-www-form-urlencoded")

						if(typeof data !== "string") {
							s = []
							for(id in data) s.push(encodeURIComponent(id).replace(/%20/g,"+") + "=" + encodeURIComponent(data[id]).replace(/%20/g,"+"))
							s = s.join("&")
						}
						else
							s = data.replace(/%20/g,"+")
					}
				}
				else if(mth === "put")	{
					//@sys: Explorer 6,7,8,9 / Opera 10.52 / Opera Mobile 11 / Firefox 3 / Prism 1.0 / Flock
					//			Put a string with a null character (charcode 0) send only the first part of the string
					//			before the fist 0 (null). Firefox 3/Prism/Flock workaround with sendAsBinary

					s = data + ""//!
					if(s.indexOf(String.fromCharCode(0)) !== -1)	throw jsl.ParamError("BadCharacter:data:null(charcode=0)")//!
				}

				//2.2-data sending
				//-------------------------------------------------------------------------------
				//@sys: Explorer All - xhr.send in a put (if the resource exists) it is updated but is raised an error
				//@sys: Netscape/Flock - if null throw an error on HTTP GET
				try 			{	ncn.send(s || "") }
				catch(e) 	{ if(this.__ni_cnt_herr(cn, ncn.status) ) throw e }

				//if you try to read the xhr.status when async = true ffox throw an
				//error: status NS_ERROR_NOT_AVAILABLE
				if(!dt.async && this.__ni_cnt_herr(cn, ncn.status))
					throw jsl.NativeError("ComunicationError", [ dt.url, "(code: " + ncn.status + ")" ])

				v = dt.async ? cn : dt.data || ""
			}

			return v
		}
		catch(e) {
			jsl.throwError(e, this, arguments)
		}
	}
	//-------------------------------------------------------------------------------
	jsl.__ni_cnt_hclean = function(dt) {
		var cns, cn, a, l

		dt.state = 2
		cn = dt.cn

		cns = cn.__ni_cns
		l		= cns.length

		for(a = 0; a < l; a++)
			if(cns[a] === dt) {
				cns.splice(a, 1)

				if(dt.src) {
					dt.ncn.parentNode.removeChild(dt.ncn)
					delete jsl[dt.id]
				}
				else if(dt.ncn.readyState !== 4)
					dt.ncn.abort()

				break
			}
	}
	}

